package com.xunqi.weixinpar.controller.wxpar;

import com.xunqi.weixinpar.controller.wxpar.sdk.MyConfig;
import com.xunqi.weixinpar.controller.wxpar.sdk.WXPay;
import com.xunqi.weixinpar.controller.wxpar.sdk.WXPayUtil;
import com.xunqi.weixinpar.entity.Order;
import com.xunqi.weixinpar.service.OrderService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping(value = "/WxPay")
public class WxParController {
    @Resource
    private OrderService orderService;

    @RequestMapping(value = "/Pay")
    public String wxpar(HttpServletRequest request, HttpServletResponse response,@RequestParam(value = "orderNO",required = true) String orderNo){
        Order order=orderService.findByOrderNo(orderNo);

        try {
            PrintWriter out=response.getWriter();

            MyConfig config=new MyConfig();
            WXPay wxPay=new WXPay(config);
            Map<String,String> data=new HashMap<>();
            data.put("body",order.getBody());       //商品简单描述
            data.put("out_trade_no",order.getOrderNO());    //商户系统内部订单号
            data.put("device_info","WEB");      //自定义参数，可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
            data.put("fee_type","CNY");         //标价币种,默认人民币：CNY
            int total_fee=(int)(order.getAmount()*100);
            data.put("total_fee",total_fee+"");     //订单总金额，单位为分
            data.put("spbill_create_ip",getRemortIP(request));      //用户的客户端IP
            data.put("notify_url",config.getNotifyUrl());           //
            data.put("trade_type","NATIVE");    //指定扫码支付
            data.put("product_id","1");         //商品ID

            Map<String,String> resp=wxPay.unifiedOrder(data);
            System.out.println(resp);

            if(resp.get("return_code").equals("SUCCESS")&&resp.get("result_code").equals("SUCCESS")){
                request.setAttribute("code_url",resp.get("code_url"));
                request.setAttribute("orderNO",order.getOrderNO());
                return "showQRCode";
            }else{
                request.setAttribute("error",resp.toString());
                return "404";
//                out.print(resp.toString());
            }
        }catch (Exception e){
//            e.printStackTrace();
            request.setAttribute("error",e.toString());
            return "404";
        }
    }

    @RequestMapping(value = "/OrderQuery")
    @ResponseBody
    private String orderQuery(HttpServletRequest request, HttpServletResponse response,@RequestParam(value = "orderNO",required = true) String orderNo){
        Order order=orderService.findByOrderNo(orderNo);

        //如果订单状态为1，说明已支付，直接返回SUCCESS
        //否则，去查一下微信后台，看看是否支付成功。
        //如果微信后台的状态为成功，则修改订单状态。
        if (order.getStatus()==1){
            return "SUCCESS";
        }else {

            try {
                MyConfig myConfig=new MyConfig();
                WXPay wxPay=new WXPay(myConfig);

                Map<String,String> data=new HashMap<>();
                data.put("out_trade_no",orderNo);

                Map<String,String> resp=wxPay.unifiedOrder(data);
                System.out.println(resp.toString());

                if ("SUCCESS".equals(resp.get("return_code"))&&"SUCCESS".equals(resp.get("result_code"))){
                    if ("SUCCESS".equals(resp.get("trade_state"))){
                        if (order!=null&& order.getStatus()==0){
                            //修改订单
                            order.setStatus(1);
                            order.setPayType(2);
                            order.setTrade_no(resp.get("transaction_id"));
                            orderService.updateStatus(order);
                        }
                    }
                    return resp.get("trade_state");
                }else{
                    System.out.println(resp.toString());
                    return resp.toString();
                }
            }catch (Exception e){
                return e.toString();
            }
        }
    }

    @RequestMapping(value = "/Notify")
    @ResponseBody
    public String notify(HttpServletRequest request, HttpServletResponse response){
        try{
            String notifyData="";       //支付结果通知的xml数据
            //1.从request获取xml流，转化成为MAP数据
            InputStream inputStream=request.getInputStream();
            BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
            StringBuffer sb=new StringBuffer();
            String temp;
            while ((temp=reader.readLine())!=null){
                sb.append(temp);
            }
            reader.close();
            inputStream.close();

            notifyData=sb.toString();

            MyConfig myConfig=new MyConfig();
            WXPay wxPay=new WXPay(myConfig);

            Map<String,String> notifyMap=WXPayUtil.xmlToMap(notifyData);    //转成map

            //对数据进行签名
            if (wxPay.isResponseSignatureValid(notifyMap)){
                //签名正确
                //进行处理
                //注意特殊情况：清单已经退款，但收到了支付结果成功的通知，不应把商户测订单状态从退款改成支付成功

                String returnCode=notifyMap.get("return_code");
                if (returnCode.equals("SUCCESS")){
                    if (notifyMap.get("result_code").equals("SUCCESS")){
                        //微信支付订单号
                        String transactionId=notifyMap.get("transaction_id");
                        //商务订单号
                        String outTradeNo=notifyMap.get("out_trade_no");
                        Order order=orderService.findByOrderNo(outTradeNo);
                        if (order!=null&&order.getStatus()==0){
                            order.setPayType(2);
                            order.setStatus(1);
                            order.setTrade_no(transactionId);
                            orderService.updateStatus(order);
                        }
                        System.out.println("微信支付成功");
                    }else{
                        System.out.println("微信支付失败，"+notifyMap.get("err_code")+"---"+notifyMap.get("err_code_des"));
                    }
                }else{
                    System.out.println("微信支付失败,"+notifyMap.get("return_msg"));
                }

                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            }else{
                //签名错误，如果数据里没有sign字段，也以为是签名错误
                System.out.println("微信支付异步通知，签名错误");
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>";
            }
        }catch (Exception e){
            e.printStackTrace();
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>";
        }
    }

    private String getRemortIP(HttpServletRequest request){
        if (request.getHeader("x-forwarded-for")==null){
            return request.getRemoteAddr();
        }
        return request.getHeader("x-forwarded-for");
    }

}
